/*
Copyright (c) 2022 George Bartolomey 

Этот файл — часть w2midi_qt.

w2midi_qt — свободная программа: вы можете перераспространять ее и/или изменять ее на условиях Стандартной общественной лицензии GNU в том виде, в каком она была опубликована Фондом свободного программного обеспечения; версии 3.

w2midi_qt распространяется в надежде, что она будет полезной, но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной общественной лицензии GNU.

Вы должны были получить копию Стандартной общественной лицензии GNU вместе с этой программой. Если это не так, см. <https://www.gnu.org/licenses/>.
*/

#include <QtWidgets>
#include "app.h"
#include "cli.h"
#include "slider.h"

App::App()
{
    minBufferSizePower = 5; // 2^5
    cli = new W2MidiCli(this);
    QVBoxLayout *vbox = new QVBoxLayout();
    setLayout(vbox);
    QScrollArea *log_sa = new QScrollArea();
    log = new QLabel();
    log->setWordWrap(true);
    log->setAlignment(Qt::AlignmentFlag::AlignTop | Qt::AlignmentFlag::AlignLeft);
    log_sa->setWidgetResizable(true);
    log_sa->setWidget(log);
    vbox->addWidget(log_sa);
    QHBoxLayout *controls_layout = new QHBoxLayout();
    vbox->addLayout(controls_layout, 2);
    Slider *bufferSize = new Slider(0, 10, 5, 10, tr("Buffer size"), [=](int val) {
        return QString::number(1 << (val + minBufferSizePower)) + " " + tr("samples");
    });
    controls_layout->addWidget(bufferSize);
    Slider *ampThreshold = new Slider(0, 50, 20, 20, tr("Amplitude threshold"), [](int val) { return QString::number(val) + " " + tr("decibels"); });
    controls_layout->addWidget(ampThreshold);
    Slider *accThreshold = new Slider(0, 100, 20, 20, tr("Accuracy threshold"), [](int val) { return QString::number(val) + "%"; });
    controls_layout->addWidget(accThreshold);
    QLineEdit *clientName = new QLineEdit("w2midi");
    vbox->addWidget(new QLabel(tr("Client name") + ":"));
    vbox->addWidget(clientName);
    QHBoxLayout *buttons = new QHBoxLayout();
    vbox->addLayout(buttons);
    startstopButton = new QPushButton(tr("Start"));
    applyButton = new QPushButton(tr("Apply"));
    buttons->addWidget(startstopButton);
    buttons->addWidget(applyButton);
    applyButton->setEnabled(false);
    
    connect(bufferSize, &Slider::valueChanged, cli, [=](int value) {
        cli->setBufferSize(1 << (value + minBufferSizePower));
    });
    connect(ampThreshold, &Slider::valueChanged, cli, [=](int value) { cli->setAmpThreshold(value); });
    connect(accThreshold, &Slider::valueChanged, cli, [=](int value) { cli->setAccThreshold(value * 0.01); });
    connect(clientName, &QLineEdit::textChanged, cli, [=](QString value) { cli->setClientName(value); });
    
    connect(bufferSize, &Slider::valueChanged, this, &App::enableApply);
    connect(ampThreshold, &Slider::valueChanged, this, &App::enableApply);
    connect(accThreshold, &Slider::valueChanged, this, &App::enableApply);
    connect(clientName, &QLineEdit::textChanged, this, &App::enableApply);

    connect(startstopButton, &QPushButton::clicked, this, &App::startStop);
    connect(applyButton, &QPushButton::clicked, cli, [=]() {
        cli->restart();
        applyButton->setEnabled(false);
    });
    connect(cli, &W2MidiCli::processStateChanged, this, [=](bool running) {
        if (running)
            startstopButton->setText(tr("Stop"));
        else
            startstopButton->setText(tr("Start"));
    });
    connect(cli, &W2MidiCli::errorOccurred, log, [=](QString text){
        log->setText(log->text() + text);
        QScrollBar *scrollBar = log_sa->verticalScrollBar();
        scrollBar->setValue(scrollBar->maximum());
    });
}

void App::startStop()
{
    if (!cli->getProcessState()) {
        log->setText("");
        cli->start();
    }
    else {
        cli->stop();
    }
}

void App::enableApply()
{
    applyButton->setEnabled(cli->getProcessState());
}
